/*
 * 版权所有 2009-2022山东新北洋信息技术股份有限公司 保留所有权利。
 */
package online.xuping.thousandsOfWorlds.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import online.xuping.thousandsOfWorlds.common.cache.CacheCustomKeyGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 缓存配置类
 *
 * @author dongyinggang
 * @date 2022/9/8 18:09
 * @copyright 2022 山东新北洋信息技术股份有限公司. All rights reserved
 */
@Slf4j
@Configuration
public class CacheConfig extends CachingConfigurerSupport {

    public static final int SIX_HUNDRED = 600;
    public static final int ONE_HUNDRED = 100;
    public static final int ONE_THOUSAND = 1000;
    @Autowired
    private CacheCustomKeyGenerator cacheCustomKeyGenerator;
    @Autowired
    private ExecutorService commonThreadPool;

    /**
     * 设置自定义key生成器
     *
     * @return {@link KeyGenerator 自定义key生成器 }
     * @author dongyinggang
     * @date 2022/9/9 10:48
     **/
    @Bean
    @Primary
    @Override
    public KeyGenerator keyGenerator() {

        return cacheCustomKeyGenerator;
    }

    /**
     * 配置缓存管理器
     *
     * @return 缓存管理器
     */
    @Override
    @Primary
    @Bean("caffeineCacheManager")
    public CacheManager cacheManager() {
        Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
                // 设置最后一次写入后经过固定时间过期
                .expireAfterWrite(SIX_HUNDRED, TimeUnit.SECONDS)
                // 初始的缓存空间大小
                .initialCapacity(ONE_HUNDRED)
                // 缓存的最大条数
                .maximumSize(ONE_THOUSAND)
                //记录删除缓存原因
                .removalListener((key, value, cause) -> log.info(">>> 删除缓存 [{}]({}), reason is [{}]", key, value, cause))
                //指定删除的异步线程来源为公共线程池
                .executor(commonThreadPool)
                // 开启状态监控
                .recordStats();

        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(caffeine);


        return cacheManager;
    }
}
